# -*- coding: utf-8 -*-
import pickle
import numpy as np
from . import configuration as cfg
import math
import os


# 定义神经元
class neuron(object):
    def __init__(self, layer_id, neuron_id, node_x, node_y, nodenumber):
        self.layer_id = layer_id
        self.neuron_id = neuron_id
        # 目的神经元id
        self.dst = []
        # 连接的权重
        self.weight = []
        # node坐标
        self.node_x = node_x
        self.node_y = node_y
        self.nodenumber = nodenumber
        # 需要的连接格式
        self.link = {}


def intToBin8(num):
    str_num = (bin(((1 << 8) - 1) & num)[2:]).zfill(8)
    num = int(str_num, 2)
    ans = '{:02x}'.format(num)
    return ans


def binTohex(num):
    num = int(num, 2)
    ans = '{:02X}'.format(num)
    return ans


# 建立网络
def buildNetwork(ID, connfiles, netDepth, layerWidth, node_list, zerolist, delay, vth, leak, reset, leaksign, grid_size=64):
    '''
    connfiles:list,层与层之间的连接文件
    netDepth: int, 网络深度
    layerWidth: list, 不包括输入层的每层网络的大小
    nodelist：list, 每层分配的节点信息
    zerolist: list, 每层的原点坐标
    return：
    '''
    neuronNet = []
    nodeNet = []
    # 初始化网络形状，len(neuronNet) = netDepth - 1
    for i in range(netDepth):
        layer = []
        for j in range(layerWidth[i]):
            layer.append(neuron)
        neuronNet.append(layer)

    # 初始化nodeNet，相当于是x*y的矩形，模拟芯片的node
    for x in range(grid_size + 1):
        x_loop = []
        for y in range(grid_size + 1):
            x_loop.append([])
        nodeNet.append(x_loop)

    # 实例化每个神经元，neuronNet[i][j]表示第i层的第j个神经元的信息
    for i in range(netDepth):  # 每层
        # print(i,netDepth)
        neuron_num = int(math.ceil(layerWidth[i] / float(len(node_list[i]))))  # 根据该层node数量，确定每个node分配的神经元数量,向上取整
        print('neuron_num:', neuron_num)
        for j in range(layerWidth[i]):  # 该层每个神经元
            node_x = node_list[i][j // neuron_num][0]
            node_y = node_list[i][j // neuron_num][1]
            nodenumber = node_x * grid_size + node_y
            neuronNet[i][j] = neuron(i, j, node_x, node_y, nodenumber)

        # 解析每层的连接
        if i != netDepth - 1:
            print(connfiles[i])
            f = open(connfiles[i], 'rb')
            # conn = np.array(pickle.load(f))
            conn = np.array(pickle.load(f, encoding='iso-8859-1'))
            for line in conn:
                src = int(line[0])
                dst = int(line[1])
                weight = intToBin8(int(line[2]))  # 有时候要*1000
                neuronNet[i][src].dst.append(dst)
                neuronNet[i][src].weight.append(weight)
    # print("aaaaaaaaaaaa")
    # 生成link
    for i in range(netDepth - 1):  # 每层
        # neuron_num = layerWidth[i+1] // len(node_list[i+1])  # 根据下层node数量，确定连接到哪个神经元
        neuron_num = int(math.ceil(layerWidth[i + 1] / float(len(node_list[i + 1]))))
        print(i, neuron_num)
        for j in range(layerWidth[i]):  # 该层每个神经元
            for l in range(len(neuronNet[i][j].dst)):  # 每个连接
                dst = neuronNet[i][j].dst[l]
                weight = neuronNet[i][j].weight[l]
                node_x = neuronNet[i + 1][int(dst)].node_x
                node_y = neuronNet[i + 1][int(dst)].node_y  #目的node 坐标
                nodenumber = neuronNet[i + 1][int(dst)].nodenumber

                if nodenumber not in neuronNet[i][j].link.keys():
                    neuronNet[i][j].link[nodenumber] = []
                neuronNet[i][j].link[nodenumber].append(int(binTohex(bin(dst % neuron_num)) + weight, 16))
            # 建立每个神经元
            n = cfg.neuron(neuronNet[i][j].link)
            node_x = neuronNet[i][j].node_x
            node_y = neuronNet[i][j].node_y
            nodeNet[node_x][node_y].append(n)

    nos = []
    # 最后的输出节点(即最后一层)不需要配置，所以 len(node_list)-1
    # for i in range(len(node_list)-1):
    #     for x,y in node_list[i]:
    #         nodenumber = x * grid_size + y
    #         nos.append(cfg.node(nodenumber,zero_ref[i],nodeNet[x][y],delay,vth,leak,reset,grid_size=grid_size))

    for i in range(len(node_list) - 1):
        zero_layer = zerolist[i]
        j = 0
        for x, y in node_list[i]:
            nodenumber = x * grid_size + y
            # print(x, y, zero_layer[j])
            nos.append(
                cfg.node(nodenumber, zero_layer[j], nodeNet[x][y], delay, vth[i], leak, reset[i], grid_size=grid_size))
            j += 1

    conf = cfg.configuration(nos)
    filename = os.path.join("config", ID +"config.txt") 
    conf.gen_config_file(filename, leaksign = leaksign)
    # print("done")


if __name__ == "__main__":
    connfiles = [
        "connections2/0_to_2",
        "connections2/2_to_4",
        'connections2/4_to_6',
        'connections2/6_to_8',
        'connections2/8_to_10',
        'connections2/10_to_12',
        'connections2/12_to_14',
        'connections2/14_to_16',
        'connections2/16_to_18'
    ]
    netDepth = 3
    layerWidth = [784, 12544, 12544, 12544, 12544, 3136, 6272, 1568, 100, 10, 1]
    layer = []
    node_list = [[(24, 24), (25, 24), (26, 24), (27, 24), (28, 24), (29, 24), (30, 24), (31, 24), (32, 24), (33, 24), (34, 24), (35, 24), (36, 24), (37, 24), (38, 24), (39, 24), (40, 24), (41, 24), (42, 24), (43, 24), (44, 24), (45, 24), (46, 24), (47, 24), (24, 25), (25, 25), (26, 25), (27, 25), (28, 25), (29, 25), (30, 25), (31, 25), (32, 25), (33, 25), (34, 25), (35, 25), (36, 25), (37, 25), (38, 25), (39, 25), (40, 25), (41, 25), (42, 25), (43, 25), (44, 25), (45, 25), (46, 25), (47, 25), (24, 26), (25, 26), (26, 26), (27, 26), (28, 26), (29, 26), (30, 26), (31, 26), (32, 26), (33, 26), (34, 26), (35, 26), (36, 26), (37, 26), (38, 26), (39, 26), (40, 26), (41, 26), (42, 26), (43, 26), (44, 26), (45, 26), (46, 26), (47, 26), (24, 27), (25, 27), (26, 27), (27, 27), (28, 27), (29, 27), (30, 27), (31, 27), (32, 27), (33, 27), (34, 27), (35, 27), (36, 27), (37, 27), (38, 27), (39, 27), (40, 27), (41, 27), (42, 27), (43, 27), (44, 27), (45, 27), (46, 27), (47, 27), (24, 28), (25, 28), (26, 28), (27, 28), (28, 28), (29, 28), (30, 28), (31, 28), (32, 28), (33, 28), (34, 28), (35, 28), (36, 28), (37, 28), (38, 28), (39, 28), (40, 28), (41, 28), (42, 28), (43, 28), (44, 28), (45, 28), (46, 28), (47, 28), (24, 29), (25, 29), (26, 29), (27, 29), (28, 29), (29, 29), (30, 29), (31, 29), (32, 29), (33, 29), (34, 29), (35, 29), (36, 29), (37, 29), (38, 29), (39, 29), (40, 29), (41, 29), (42, 29), (43, 29), (44, 29), (45, 29), (46, 29), (47, 29), (24, 30), (25, 30), (26, 30), (27, 30), (28, 30), (29, 30), (30, 30), (31, 30), (32, 30), (33, 30), (34, 30), (35, 30), (36, 30), (37, 30), (38, 30), (39, 30), (40, 30), (41, 30), (42, 30), (43, 30), (44, 30), (45, 30), (46, 30), (47, 30), (24, 31), (25, 31), (26, 31), (27, 31), (28, 31), (29, 31), (30, 31), (31, 31), (32, 31), (33, 31), (34, 31), (35, 31), (36, 31), (37, 31), (38, 31), (39, 31), (40, 31), (41, 31), (42, 31), (43, 31), (44, 31), (45, 31), (46, 31), (47, 31), (24, 32), (25, 32), (26, 32), (27, 32), (28, 32), (29, 32), (30, 32), (31, 32), (32, 32), (33, 32), (34, 32), (35, 32), (36, 32), (37, 32), (38, 32), (39, 32), (40, 32), (41, 32), (42, 32), (43, 32), (44, 32), (45, 32), (46, 32), (47, 32), (24, 33), (25, 33), (26, 33), (27, 33), (28, 33), (29, 33), (30, 33), (31, 33), (32, 33), (33, 33), (34, 33), (35, 33), (36, 33), (37, 33), (38, 33), (39, 33), (40, 33), (41, 33), (42, 33), (43, 33), (44, 33), (45, 33), (46, 33), (47, 33), (24, 34), (25, 34), (26, 34), (27, 34), (28, 34), (29, 34), (30, 34), (31, 34), (32, 34), (33, 34), (34, 34), (35, 34), (36, 34), (37, 34), (38, 34), (39, 34), (40, 34), (41, 34), (42, 34), (43, 34), (44, 34), (45, 34), (46, 34), (47, 34), (24, 35), (25, 35), (26, 35), (27, 35), (28, 35), (29, 35), (30, 35), (31, 35), (32, 35), (33, 35), (34, 35), (35, 35), (36, 35), (37, 35), (38, 35), (39, 35), (40, 35), (41, 35), (42, 35), (43, 35), (44, 35), (45, 35), (46, 35), (47, 35), (24, 36), (25, 36), (26, 36), (27, 36)], [(24, 37), (24, 40), (24, 41), (24, 44), (24, 45), (25, 37), (25, 38), (25, 41), (24, 38), (24, 39), (24, 42), (24, 43), (24, 46), (24, 47), (25, 39), (25, 40), (25, 42), (25, 43), (25, 44), (25, 45), (25, 46), (25, 47), (26, 37), (26, 38), (26, 39), (26, 40), (26, 41), (26, 42), (26, 43), (26, 44), (26, 45), (26, 46), (26, 47), (27, 37), (27, 38), (27, 39), (27, 40), (27, 41), (27, 42), (27, 43), (27, 44), (27, 45), (27, 46), (27, 47), (28, 36), (28, 37), (28, 38), (28, 39), (28, 40), (28, 41), (28, 42), (28, 43), (28, 44), (28, 45), (28, 46), (28, 47), (29, 36), (29, 37), (29, 38), (29, 39), (29, 40), (29, 41), (29, 42), (29, 43), (29, 44), (29, 45), (29, 46), (29, 47), (30, 36), (30, 37), (30, 38), (30, 39), (30, 40), (30, 41), (30, 42), (30, 43), (30, 44), (30, 45), (30, 46), (30, 47), (31, 36), (31, 37), (31, 38), (31, 39), (31, 40), (31, 41), (31, 42), (31, 43), (31, 44), (31, 45), (31, 46), (31, 47), (32, 36), (32, 37), (32, 38), (32, 39), (32, 40), (32, 41), (32, 42), (32, 43), (32, 44), (32, 45), (32, 46), (32, 47), (33, 36), (33, 37), (33, 38), (33, 39), (33, 40), (33, 41), (33, 42), (33, 43), (33, 44), (33, 45), (33, 46), (33, 47), (34, 36), (34, 37), (34, 38), (34, 39), (34, 40), (34, 41), (34, 42), (34, 43), (34, 44), (34, 45), (34, 46), (34, 47), (35, 36), (35, 37), (35, 38), (35, 39), (35, 40), (35, 41), (35, 42), (35, 43), (35, 44), (35, 45), (35, 46), (35, 47), (36, 36), (36, 37), (36, 38), (36, 39), (36, 40), (36, 41), (36, 42), (36, 43), (36, 44), (36, 45), (36, 46), (36, 47), (37, 36), (37, 37), (37, 38), (37, 39), (37, 40), (37, 41), (37, 42), (37, 43), (37, 44), (37, 45), (37, 46), (37, 47), (38, 36), (38, 37), (38, 38), (38, 39), (38, 40), (38, 41), (38, 42), (38, 43), (38, 44), (38, 45), (38, 46), (38, 47), (39, 36), (39, 37), (39, 38), (39, 39), (39, 40), (39, 41), (39, 42), (39, 43), (39, 44), (39, 45), (39, 46), (39, 47), (40, 47), (41, 47), (42, 47), (43, 47), (44, 47), (45, 47), (46, 47), (47, 47), (40, 46), (41, 46), (42, 46), (43, 46), (44, 46), (45, 46), (46, 46), (47, 46), (40, 45), (41, 45), (42, 45), (43, 45), (44, 45), (45, 45), (46, 45), (47, 45), (40, 44), (41, 44), (42, 44), (43, 44), (44, 44), (45, 44), (46, 44), (47, 44), (40, 43), (41, 43), (42, 43), (43, 43), (44, 43), (45, 43), (46, 43), (47, 43), (40, 42)]]
    node = [(48, 24), (51, 24), (53, 24), (55, 24), (57, 24), (49, 24), (50, 24), (52, 24), (54, 24), (56, 24), (58, 24), (59, 24), (60, 24), (61, 24), (62, 24), (63, 24), (48, 25), (49, 25), (50, 25), (51, 25), (52, 25), (53, 25), (54, 25), (55, 25), (56, 25), (57, 25), (58, 25), (59, 25), (60, 25), (61, 25), (62, 25), (63, 25), (48, 26), (49, 26), (50, 26), (51, 26), (52, 26), (53, 26), (54, 26), (55, 26), (56, 26), (57, 26), (58, 26), (59, 26), (60, 26), (61, 26), (62, 26), (63, 26), (48, 27), (49, 27), (50, 27), (51, 27), (52, 27), (53, 27), (54, 27), (55, 27), (56, 27), (57, 27), (58, 27), (59, 27), (60, 27), (61, 27), (62, 27), (63, 27), (48, 28), (49, 28), (50, 28), (51, 28), (52, 28), (53, 28), (54, 28), (55, 28), (56, 28), (57, 28), (58, 28), (59, 28), (60, 28), (61, 28), (62, 28), (63, 28), (48, 29), (49, 29), (50, 29), (51, 29), (52, 29), (53, 29), (54, 29), (55, 29), (56, 29), (57, 29), (58, 29), (59, 29), (60, 29), (61, 29), (62, 29), (63, 29), (48, 30), (49, 30), (50, 30), (51, 30), (52, 30), (53, 30), (54, 30), (55, 30), (56, 30), (57, 30), (58, 30), (59, 30), (60, 30), (61, 30), (62, 30), (63, 30), (48, 31), (49, 31), (50, 31), (51, 31), (52, 31), (53, 31), (54, 31), (55, 31), (56, 31), (57, 31), (58, 31), (59, 31), (60, 31), (61, 31), (62, 31), (63, 31), (48, 32), (49, 32), (50, 32), (51, 32), (52, 32), (53, 32), (54, 32), (55, 32), (56, 32), (57, 32), (58, 32), (59, 32), (60, 32), (61, 32), (62, 32), (63, 32), (48, 33), (49, 33), (50, 33), (51, 33), (52, 33), (53, 33)]
    node_list.append(node)
    zerolist = [[(24, 37), (24, 37), (24, 39), (24, 41), (24, 41), (24, 37), (24, 37), (24, 37), (24, 37), (24, 38), (24, 37), (24, 37), (24, 37), (24, 39), (24, 41), (24, 43), (24, 37), (24, 37), (24, 37), (25, 37), (24, 38), (24, 38), (24, 38), (24, 39), (24, 41), (24, 42), (24, 42), (24, 37), (24, 37), (24, 37), (25, 37), (25, 37), (25, 37), (25, 37), (25, 38), (25, 39), (25, 39), (25, 37), (25, 37), (25, 37), (26, 37), (26, 37), (26, 37), (26, 37), (26, 38), (26, 36), (26, 36), (26, 36), (26, 37), (26, 37), (26, 38), (26, 39), (26, 37), (26, 37), (27, 37), (27, 36), (27, 36), (27, 36), (27, 36), (27, 37), (27, 36), (27, 36), (27, 36), (27, 37), (27, 37), (27, 38), (27, 36), (27, 36), (28, 36), (28, 37), (28, 38), (28, 36), (28, 36), (28, 37), (28, 37), (28, 36), (28, 36), (28, 36), (28, 36), (28, 37), (28, 38), (28, 36), (28, 36), (29, 36), (29, 37), (29, 37), (29, 36), (29, 36), (29, 36), (29, 37), (29, 37), (29, 36), (29, 36), (29, 36), (29, 37), (29, 38), (29, 36), (29, 36), (30, 36), (30, 36), (30, 37), (30, 36), (30, 36), (30, 36), (30, 36), (30, 37), (30, 36), (30, 36), (30, 36), (30, 36), (30, 37), (30, 38), (30, 36), (30, 36), (31, 36), (31, 37), (31, 38), (31, 36), (31, 36), (31, 36), (31, 37), (31, 38), (31, 36), (31, 36), (31, 36), (31, 37), (31, 38), (31, 36), (31, 36), (32, 36), (32, 37), (32, 37), (32, 36), (32, 36), (32, 36), (32, 37), (32, 37), (32, 36), (32, 36), (32, 36), (32, 37), (32, 37), (32, 36), (32, 36), (33, 36), (33, 36), (33, 37), (33, 36), (33, 36), (33, 36), (33, 36), (33, 37), (33, 36), (33, 36), (33, 36), (33, 36), (33, 37), (33, 38), (33, 36), (33, 36), (34, 36), (34, 37), (34, 38), (34, 36), (34, 36), (34, 36), (34, 37), (34, 38), (34, 36), (34, 36), (34, 36), (34, 37), (34, 38), (34, 36), (34, 36), (35, 36), (35, 37), (35, 37), (35, 36), (35, 36), (35, 36), (35, 37), (35, 37), (35, 36), (35, 36), (35, 36), (35, 37), (35, 37), (35, 38), (35, 36), (35, 36), (36, 36), (36, 37), (36, 36), (36, 36), (36, 36), (36, 36), (36, 37), (36, 36), (36, 36), (36, 36), (36, 36), (36, 37), (36, 38), (36, 36), (36, 36), (37, 36), (37, 37), (37, 38), (37, 36), (37, 36), (37, 36), (37, 37), (37, 38), (37, 36), (37, 36), (37, 36), (37, 37), (37, 38), (37, 36), (37, 36), (38, 36), (38, 36), (38, 37), (38, 36), (38, 36), (38, 36), (38, 37), (38, 37), (38, 38), (38, 39), (38, 40), (38, 40), (38, 41), (38, 42), (38, 36), (39, 36), (39, 36), (39, 37), (39, 38), (39, 39), (39, 39), (39, 40), (39, 41), (39, 42), (39, 42), (39, 43), (39, 44), (39, 45), (39, 46), (39, 45), (39, 45), (40, 45), (41, 45), (41, 45), (42, 45), (43, 45), (44, 45), (45, 45), (46, 45), (40, 44), (40, 44), (40, 44), (40, 44), (41, 44), (42, 44), (43, 44), (44, 44), (45, 44), (45, 44), (40, 43), (40, 43), (40, 43), (40, 43), (41, 43), (42, 43), (43, 43), (44, 43), (44, 43), (45, 43), (40, 42), (40, 42), (40, 43), (40, 43), (41, 43), (42, 43), (42, 43), (43, 43), (44, 43), (45, 43), (40, 42), (40, 42)], [(48, 24), (48, 24), (48, 24), (51, 24), (52, 24), (54, 24), (54, 24), (49, 24), (48, 24), (48, 24), (48, 24), (50, 24), (52, 24), (53, 24), (54, 24), (49, 24), (48, 24), (48, 24), (48, 24), (49, 24), (50, 24), (50, 24), (51, 24), (52, 24), (48, 24), (48, 24), (48, 24), (49, 24), (50, 24), (50, 24), (51, 24), (52, 24), (48, 24), (48, 25), (48, 25), (49, 25), (49, 25), (50, 25), (51, 25), (52, 25), (48, 25), (48, 25), (48, 25), (49, 25), (49, 25), (50, 25), (51, 25), (51, 25), (48, 25), (48, 25), (48, 25), (49, 25), (49, 25), (50, 25), (51, 25), (51, 25), (52, 25), (48, 25), (48, 26), (48, 26), (49, 26), (50, 26), (51, 26), (51, 26), (52, 26), (48, 26), (48, 26), (48, 26), (49, 26), (50, 26), (50, 26), (51, 26), (52, 26), (48, 26), (48, 26), (48, 26), (49, 26), (50, 26), (50, 26), (51, 26), (52, 26), (48, 26), (48, 27), (48, 27), (49, 27), (50, 27), (50, 27), (51, 27), (52, 27), (48, 27), (48, 27), (48, 27), (49, 27), (49, 27), (50, 27), (51, 27), (52, 27), (48, 27), (48, 27), (48, 27), (49, 27), (49, 27), (50, 27), (51, 27), (51, 27), (48, 27), (48, 28), (48, 28), (49, 28), (49, 28), (50, 28), (51, 28), (51, 28), (52, 28), (48, 28), (48, 28), (48, 28), (49, 28), (50, 28), (51, 28), (51, 28), (52, 28), (48, 28), (48, 28), (48, 28), (49, 28), (50, 28), (50, 28), (51, 28), (52, 28), (48, 28), (48, 29), (48, 29), (49, 29), (50, 29), (50, 29), (51, 29), (52, 29), (48, 29), (48, 29), (48, 29), (49, 29), (50, 29), (50, 29), (51, 29), (52, 29), (48, 29), (48, 29), (48, 29), (49, 29), (49, 29), (50, 29), (51, 29), (51, 29), (48, 29), (48, 30), (48, 30), (49, 30), (49, 30), (50, 30), (51, 30), (51, 30), (48, 30), (48, 30), (48, 30), (49, 30), (49, 30), (50, 30), (51, 30), (51, 30), (52, 30), (48, 30), (48, 30), (48, 30), (49, 30), (50, 30), (51, 30), (51, 30), (52, 30), (48, 30), (48, 31), (48, 31), (49, 31), (50, 31), (50, 31), (51, 31), (52, 31), (48, 31), (48, 31), (48, 31), (49, 31), (50, 31), (50, 31), (51, 31), (52, 31), (48, 31), (48, 31), (48, 31), (49, 31), (50, 31), (50, 31), (51, 31), (52, 31), (48, 31), (48, 32), (48, 32), (49, 32), (49, 32), (50, 32), (51, 32), (51, 32), (48, 32), (48, 32), (48, 32), (49, 32), (49, 32), (50, 32), (51, 32), (51, 32), (48, 32), (48, 32), (48, 32), (49, 32), (49, 32), (50, 32), (51, 32), (51, 32), (52, 32), (52, 32)]]
    vth = [50, 50, 50, 50, 50, 50]
    reset_mode = [0, 0, 0, 0, 0, 0]
    buildNetwork("0",connfiles[1:3], 3, layerWidth[1:4], node_list, zerolist, [0xaaaaaaaa, 0xaaaaaaaa], vth[0:2], 0, reset_mode[0:2], -1)



